<?

/**	
 *	Social.gmap OBJECT
 *	
 *	frontend google maps module
 *	communication between google maps api and engine based location (single and multiple)
 *	
 * 	the class is documented in the file itself. if you find any bugs help us out and report them. 
 * 	if you report a bug, make sure you give us enough information (include your code).
 *
 *	see the json examples at the bottom of this file for moddump
 *
 *	@copyright		oneDot only <we@onedotonly.be>
 * 	@copyright		Copyright (c) 2010, oneDot only. All rights reserved.
 * 	@license		BSD License
 *
 *	@author			oneDot only <we@onedotonly.be>
 */


class SocialGmap extends MOD {



	/**
	 *	constructor
	 *	
	 *	add module vars and reference (multiple modules on 1 page are possible)	
	 *	@param		array ($vars)
	 */
	 
	function __construct( $vars ) {
		$this->_addvars( $vars );
		$this->_ref();
	}
	
	
	
	/**
	 * 	define output
	 *
	 *	this is the base for rendering the google maps at the frontend
	 *	while rendering the form css is added, javascript is added
	 *
	 *	by defining a latlng in the vars you define a position for the map (center of map). 
	 *	by leaving this undefined while page is render of an object the latlng will be defined by the object's ll
	 *
	 *	@return		string - the google map
	 */
	
	function output() {
		global $Object;
				
		// CHECK LATLONG.	
		// For given object (eg /band/o/42)	
		if( !$this->vars->latlng && $Object && $ll = $Object->get( "ll" )) {
		
			$this->vars->latlng = explode( ",", $ll );
			$this->vars->objid	= $Object->id;
			$this->vars->objtype= $Object->type;
		
		} else if( $this->vars->dynamic == "childobj" && is_object( $Child = $Object->{ $this->vars->obj }) && $ll = $Child->get( "ll" ) ) { 
		
			$this->vars->latlng = explode( ",", $ll );
			$this->vars->objid	= $Child->id;
			$this->vars->objtype= $Child->type;
		
		} else if( !$this->vars->latlng ) return;
		
		if( $this->action )
			$map = $this->{ "filter_" . $this->action }();
		
		$this->js = $map;
		
		return $this->parse( "<script type='text/javascript'>" . $map . "</script>" );
		
	}
	
	
	
	/**
	 * 	render brand new google map
	 *
	 *	@return		string - javascript renders gmap
	 *	@param		array
	 */
	
	private function filter_blank () {
		
		return <<<EOT
	mod = $$( ".SocialGmap" ).pop();
	mod.insert( map = new SocialGmap( {$this->print_vars()} ).init() );
EOT;
		
	}
	
	
	
	/**	
	 *	create pinpointing gmap
	 *
	 *	@return		string - javascript (and filter_blank) renders gmap
	 */
	
	//private function filter_
	
	
	/** 
	 * filter all personal pinpoints (all users together)
	 * add a vars->limit to limit pinpoints
	 */
	
	private function filter_pinpoints() {
		global $DB, $Object;
		
		$pinpoints	= $DB->filter_objects( 'social.map', 'active ' . (( $limit = $this->vars->limit ) ? ' ORDER BY ID desc LIMIT ' . $limit : '' ));

		$clone = (array) $this->vars->markers[0];
		foreach ($pinpoints as $obj)
			if( $ll = $obj->get( "ll" ))  $markers[] = (object) array_merge( $clone, array( "ll"=> explode( ",", $ll ), "title"=> $obj->get( 'name' )));
	
		$this->vars->markers = $markers;
		return $this->filter_blank() . <<<EOT
			map.filter_markers();
EOT;

	}
	
	
	/** 
	 * filter all personal pinpoints (1 logged in user)
	 * add a vars->limit to limit pinpoints
	 */
	
	private function filter_personal_pinpoints() {
		global $DB, $Object;
		
		$pinpoints	= $DB->filter_objects( 'social.map', 'active ' . (( $uid = $_SESSION['uid'] ) ? 'AND creator = ' . $uid : '' ) . (( $limit = $this->vars->limit ) ? ' ORDER BY ID desc LIMIT ' . $limit : '' ));

		$clone = (array) $this->vars->markers[0];
		foreach ($pinpoints as $obj)
			if( $ll = $obj->get( "ll" ))  $markers[] = (object) array_merge( $clone, array( "ll"=> explode( ",", $ll ), "title"=> $obj->get( 'name' )));
	
		$this->vars->markers = $markers;
		return $this->filter_blank() . <<<EOT
			map.filter_markers();
EOT;

	}
	
	
	/**
	 * filter all pinpoints 
	 *
	 * method to filter pinpoints
	 * in case a user is logged in it will show all his/her personal pinpoints
	 * if there isn't any logged in user all pinpoints of type '$this->vars->type' will be shown
	 */ 
	private function filter_personal () {
		global $DB, $Object;

		if( $dyn = $this->vars->dynamic ) {
		
			if( $dyn == "type" && $objs = $DB->filter_objects( $this->vars->type, "active && meta like '%ll%'" . (( $_SESSION['uid'] ) ? "&& creator = '" . $_SESSION['uid'] . "'" : "") . 
				(( $limit = $this->vars->limit)? " LIMIT " . $limit : "") )) {
				
				$clone = (array) $this->vars->markers[0];
				foreach( $objs as $obj )
					if( $ll = $obj->get( "ll" ))  $markers[] = (object) array_merge( $clone, array( "ll"=> explode( ",", $ll ), "uri"=> $obj->uri(), "title"=> $obj->get( 'name' )));
										
				$this->vars->markers = $markers;
			}
				
		}
		
		return $this->filter_blank() . <<<EOT
			map.filter_markers();
EOT;

	}
	
	
	/** 
	 * filter pinpoints AND markers
	 *
	 * add (limited) personal pinpoints to the gmap
	 */
	private function filter_merged () {
		global $DB, $Object, $Engine;
		
		if ( $this->vars->dynamic == "type" ) {
		
			// normal markers
			$objs  = $DB->filter_objects ( $this->vars->type, "active && meta like '%ll%'" . (( $limit = $this->vars->limit ) ? " LIMIT " . $limit : ""));
			
			$clone = (array) $this->vars->markers[0];
			foreach( $objs as $obj )
				if( $ll = $obj->get( "ll" ))  $markers[] = (object) array_merge( $clone, array( "ll"=> explode( ",", $ll ), "uri"=> $obj->uri(), "title"=> $obj->get( 'name' )));
										
			$this->vars->markers = $markers;
			/*$pinpt = $DB->filter_objects ( "country", "active && meta like '%ll%'" . (( $limit = $this->vars->limit ) ? " LIMIT " . $limit : ""));
			
			foreach ( $pinpt as $pp ) {
				array_push($objs, $pp);
			}*/
					
			$this->vars->markers = $objs;
		
		}
		return $this->filter_blank() . <<<EOT
			map.filter_markers();
EOT;
	}
	


	// FRONTEND FILTERS (1st timers)
	// IN THE FUTURE THE MODULE SHOULD BE STABLE WITH ONLY THE NEXT FILTERS
	
	/**
	 *	filter single static map / marker
	 * 	center and marker is defined by latlng in vars
	 *
	 *	@return 	string
	 *	@param		array - latlng
	 */
	
	private function filter_single() {
		
		$this->vars->markers[0]->ll = $this->vars->latlng;
		return $this->filter_blank() . <<<EOT
			map.filter_markers();
EOT;

	}
	
	
	
	/**
	 *	filter dynamic map based on multiple types
	 *
	 *	@return		string
	 *	@param		array - types
	 */
	
	private function filter_multiple() {
		global $Object, $DB;
		
		// loop types & collect objects
		if ( $types = $this->vars->types ) {
						
			foreach( $types as $type ) {
				$clone 		= (array) (( $custom = $this->vars->markers[0]->$type )? $custom : $this->vars->markers[0] );
				$objs 		= $DB->filter_objects( $type, "active && meta like '%ll%'" . (((( $custom ) ? $custom->personal : $this->vars->markers[0]->personal )) ? " && creator = " . $_SESSION['uid'] : ""));
				
				if ( $objs ) {
					foreach( $objs as $obj ) {
						if( $ll = $obj->get( 'll' )) $markers[] = (object) array_merge( $clone, array( 'll' => explode( ',', $ll ), 'uri' => $obj->uri(), 'title' => $obj->get( 'name' )));
					}
				}
			}
			
			// check for authenticated user (add pinpoint)
			if( !$_SESSION['uid'] ) unset( $this->vars->connect );
			
			// define gmap markers
			$this->vars->markers = $markers;
		}	
		
		return $this->filter_blank() . <<<EOT
			map.filter_markers();
EOT;
	}
	
	
	
	/**
	 *	filter dynamic map based on multiple types and current $Object
	 *
	 *	@return		string
	 *	@param		array - types
	 */
	
	private function filter_social() {
		global $Object, $DB;
		
		// define centre of the map
		if( $this->vars->objid && $objtype =  $this->vars->objtype ) {

			$centre	= array_pop( $DB->filter_objects( $objtype, 'ID = ' . $this->vars->objid ));

			$clone	= (array) (( $custom = $this->vars->markers[0]->$objtype ) ? $custom : $this->vars->markers[0] );
			$markers[] = (object) array_merge( $clone, array( 'll' => explode( ',', $centre->get( 'll' )), 'uri' => $centre->uri(), 'title' => $centre->get( 'name' )));
			
		}
		
		if ( $types = $this->vars->types ) {

			foreach( $types as $type ) {

				// no object type
				if ( $type != $this->vars->objtype && $refs = $DB->reference ( $Object->type, "parentid = " . $Object->id, $type, false , true ) ) {
					
					// add markers
					$clone 		= (array) (( $custom = $this->vars->markers[0]->$type )? $custom : $this->vars->markers[0] );
					$objs 		= $DB->filter_objects( $type, "active && meta like '%ll%' && ID IN (" . implode( ',', $refs ) . ")");
				
					if ( $objs ) {
						foreach( $objs as $obj ) {
							if( $ll = $obj->get( 'll' )) $markers[] = (object) array_merge( $clone, array( 'll' => explode( ',', $ll ), 'uri' => $obj->uri(), 'title' => $obj->get( 'name' )));
						}
					}
				}
			}
			
			// check for authenticated user (add pinpoint)
			if( !$_SESSION['uid'] ) unset( $this->vars->connect );
			if( $Object ) $this->vars->objectid = $Object->id;

		}	
				
		$this->vars->markers = $markers;
		
		return $this->filter_blank() . <<<EOT
			map.filter_markers();
EOT;
	}
	
	
	
	/**
	 * 	filter object map with 1 or more markers based on type
	 *
	 *	@return		string
	 *	@param	 	string - type
	 */
	 
	private function filter_marker () {
		global $Object;
		
		if( $dyn = $this->vars->dynamic ) {
			global $DB;
			
			// static map -> new function (filter_single)
			if( $dyn == "inherit" || $this->vars->obj ) {
				$this->vars->markers[0]->ll = $this->vars->latlng;
			// dynamic map based on 
			} else if( $dyn == "type" && $objs = $DB->filter_objects( $this->vars->type, "active && meta like '%ll%'" . (( $this->vars->personal) ? "&& creator = '" . $_SESSION['uid'] . "'" : ""))) {
			// else if( $dyn == "type" && $objs = $DB->filter_objects( $this->vars->type, "active && meta like '%ll%'" )) {
				
				$clone = (array) $this->vars->markers[0];
				foreach( $objs as $obj )
					if( $ll = $obj->get( "ll" ))  $markers[] = (object) array_merge( $clone, array( "ll"=> explode( ",", $ll ), "uri"=> $obj->uri(), "title"=> $obj->get( 'name' )));
										
				$this->vars->markers = $markers;
			} else if ( $dyn == 'object' ) {
				$this->vars->latlng			= explode( ',', $Object->get( 'll' ));
				$this->vars->markers[0]->ll = explode( ',', $Object->get( 'll' ));
			}
		}
		
		return $this->filter_blank() . <<<EOT
	map.filter_markers();
EOT;

	}
	
	
	function ajax_add_pinpoint() {
		global $DB, $Object, $Engine;
		
		if( $this->vars->objid && !$Object )
			$Object = new OBJECT( $this->vars->objtype, $this->vars->objid );
		
		// set name and textid
		$textid = $Engine->text->set( $this->vars->descr, null, 'long', LANG );
		$nameid = $Engine->text->set( $this->vars->name, null, 'short', LANG );

		// set social.map
		$id = $DB->set( 'social.map', array( "meta" => array( "ll" => str_replace(" ", "", substr($this->vars->ll, 1,-1))), "textid" => $textid, "nameid" => $nameid, "llog" => date('Y-m-d H:i:s', time()) ), false, true );
		
		// set reference
		$DB->set_reference( $Object->type, (int) $Object->id, "social.map" , (int) $id, true );
	
	}
	
	
	function ajax_connect() {
		global $DB, $Engine;
		
		if ( $this->vars->latlng ) $return = $this->ajax_pinpoint();
		else {		
			$Mod = new MOD_CONSTRUCT();
			$module = $Mod->get( (int) $this->vars->mod );
						
			$return = $module;
		}
		
		return $return;
	}
	
	
	function ajax_pinpoint() {
		global $Object;
			
		$Mod = new MOD_CONSTRUCT();
		$module = $Mod->request_json( (int) $this->vars->mod );
						
		$children	= (array) $module->vars->children;
		$extra	 	= array( 
						"latlng" => (object) array( "type" => "hidden", "class" => "wide req", "defined" => $this->vars->latlng->b . ',' . $this->vars->latlng->c ),	
					);
		$def = array_merge( $children, $extra );
		//print_r( $def );
		
	
	}

} 


/**
 *	example for filter_single
 *
 *
 *	{
 *	  "mod":"social.gmap",
 *	  "action":"single",
 *	  "vars":{
 *	      "box":[654,480],
 *	      "isize":[42,48],
 *	      "zoom":14,
 *	      "mapTypeControl":true,
 *	      "mapcontrol":"GSmallZoomControl3D",
 *	      "latlng":[51.146948,3.864891],
 *	      "markers":[{
 *	          "point":[20,18],
 *	          "icon":"img/mod.google.mpoint.png"
 *	      }]
 *	  }
 *	}
 *
 *
 * 	example for multiple
 *	{
 *	   "mod":"social.gmap",
 *	   "action":"multiple",
 *	   "vars":{
 *	       "box"			:[654,480],
 *	       "isize"			:[42,48],
 *	       "zoom"			:5,
 *	       "mapTypeControl"	:true,
 *	       "mapcontrol"		:"GSmallZoomControl3D",
 *	       "latlng"			:[51.146948,3.864891],
 *	       "types"			:["bestemming","country"],
 *	       "markers"		:[
 *	       		{ "bestemming" : {
 *	           			"point":[20,18],
 *	           			"icon":"img/mod.google.mpoint.png",
 *						"personal":true
 *	      				},
 *	      		  "country": {
 *	           			"point":[20,18],
 *	           			"icon":"img/custom.marker.png"
 *	      				}
 *	      		}
 *	       ]
 *	   },
 *	   "nameid":650
 *	}
 */
?>